//Copyright (c) Microsoft Corporation.  All rights reserved.

using System;
using System.Collections.Generic;
using System.Text;

namespace Eas.WebCrawler.PlugIns.RequestComparers
{
    /// <summary>Prioritizes requests whose depth (number of parents) is closest to a target depth.  Ties are broken by an inner <see cref="BaseComparer"/>.</summary>
    /// <remarks>Root requests have depth <code>0</code>.</remarks>
    public class TargetDepthComparer :DecoratingComparer
    {

        private int _Depth;

        /// <summary>The highest priority depth.</summary>
        public int Depth
        {
            get { return _Depth; }
        }

        /// <summary>Constructs a comparer from a target depth and an inner <see cref="BaseComparer"/> used to break ties.</summary>
        /// <param name="depth">The highest priority depth.</param>
        /// <param name="innerComparer">The <see cref="BaseComparer"/> used to break ties.</param>
        public TargetDepthComparer(int depth, BaseComparer innerComparer)
          :base(innerComparer)
        {
            _Depth = depth;
        }

        /// <summary>Compares two <see cref="Uri"/>s to see which is higher priority based on their depth.</summary>
        /// <param name="leftRequest">The left <see cref="Eas.WebCrawler.Interfaces.Request"/> to compare.</param>
        /// <param name="rightRequest">The right <see cref="Eas.WebCrawler.Interfaces.Request"/> to compare.</param>
        /// <returns>A <see cref="CompareResult"/> declaring if the left or right <see cref="Eas.WebCrawler.Interfaces.Request"/> is higher priority.</returns>
        public override CompareResult CompareUris(Eas.WebCrawler.Interfaces.Request leftRequest, Eas.WebCrawler.Interfaces.Request rightRequest)
        {
            int leftDistanceToTargetDepth = Math.Abs(leftRequest.Depth - _Depth);
            int rightDistanceToTargetDepth = Math.Abs(rightRequest.Depth - _Depth);
    
            if(leftDistanceToTargetDepth==rightDistanceToTargetDepth) return base.CompareUris(leftRequest, rightRequest);

            if (leftDistanceToTargetDepth < rightDistanceToTargetDepth)
                return CompareResult.LeftIsHigherPriority;
            else
                return CompareResult.RightIsHigherPriority;

        }

    }
}
